<?php
/**
 * 中转库存调整(upload)
 */
namespace App\Admin\Controllers\OverSeasBa;

use App\Importer\Inventory\CNImporter;
use App\Models\OverSeasBa\BoxAdjust;
use App\Models\OverSeasBa\Warehouse;
use App\Models\OverSeasBa\InventoryBox;
use App\Models\OverSeasBa\InventoryBoxFNSku;
use App\Util\RExcel;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Facades\Admin;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Maatwebsite\Excel\Facades\Excel;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class BoxAdjustUploadController extends AdminController{

    protected $title = '中转库存调整';

    protected function grid()
    {
        return view('overseas-ba.box-adjust-upload.index');
    }

    public function upload(Request $request){
        $file = $request->file('source_file');
        if ($file->isValid()) {
            $re = $this->_importUp($file);
            if(is_array($re)) {
                if($re['flag']){
                    admin_toastr('文件：'.$re['data'].' 上传成功！');
                }else{
                    admin_toastr($re['data'],'error');
                }
            }else{
                return $re;
            }
        }else{
            admin_toastr('无效文件！','error');
        }
        return back()->withInput();
    }

    private function _importUp(UploadedFile $file){
        try{
            $data = Excel::toArray(new CNImporter(),$file);
            $data = $data[0];
            if(!$data)return ['flag' => false,'data' => '请上传包含有数据的文件！'];
            $errors = [];
            $count = 1;
            $arr = [];
            $userId = Admin::user()->id;
            foreach($data as $row){
                $count++;
                $batchNo = $row[0] ? trim($row[0]) : '';
                $boxNo = $row[1] ? trim($row[1]) : '';
                $fnSku = $row[2] ? trim($row[2]) : '';
                $warehouse = $row[3] ? trim($row[3]) : '';
                $num = $row[4] ? trim($row[4]) : 0; //箱数
                if(!$batchNo || !$boxNo || !$fnSku || !$warehouse){
                    $errors[$count] = '必填项为空';
                    continue;
                }
                $key = $batchNo.'-'.$boxNo.'-'.$fnSku.'-'.$warehouse;
                if(!in_array($key,$arr)){
                    $arr[$count] = $key;
                }else{
                    $errors[$count] = '重复记录';
                    continue;
                }
                $warehouseId = Warehouse::getIdByCode($warehouse);
                if(!$warehouseId){
                    $errors[$count] = $warehouse.'仓库不存在，请仔细核对';
                    continue;
                }
                if(!is_numeric($num)){
                    $errors[$count] = '数量格式有误';
                    break;
                }
                if($num < 0){
                    $errors[$count] = '数量不能小于0';
                    break;
                }
                DB::beginTransaction();
                $iBox = InventoryBox::query()
                    ->where('warehouse_id',$warehouseId)
                    ->where('batch_no',$batchNo)
                    ->where('box_no',$boxNo)
                    ->where('fnsku',$fnSku)
                    ->lockForUpdate()
                    ->first();
                if(!$iBox){
                    $errors[$count] = $key.'库存不存在，请仔细核对';
                    continue;
                }
                //设数据值参数为：剩余可调整箱数（5） = 入库箱数(在库箱数)（10） - 出库箱数（5）
                $bTotal = $iBox->storage_total - $iBox->out_total;

                if($bTotal == $num){
                    //差值为0，无需调整。
                    continue;

                }elseif($bTotal > $num){
                    //设：调整箱数值为4，则调整箱数小于剩余可调整箱数，即(减)。
                    //入库箱数（9 = 10 - 1） = 入库箱数（10）-（剩余可调整箱数（5）- 调整箱数（4））
                    $iBox->storage_total -= $bTotal - $num;

                }else{
                    //设：调整箱数值为6，则调整箱数大于剩余可调整箱数，即(加)。
                    //入库箱数（11 = 10 + 1） = 入库箱数（10）+（调整箱数（6）- 剩余可调整箱数（5））
                    $iBox->storage_total += $num - $bTotal;
                }

                $aTotal = $iBox->storage_total - $iBox->out_total;
                if($aTotal < 0){
                    $errors[$count] = $key.'调整后库存小于0，请仔细核对';
                    continue;
                }
                $iBox->save();

                //更新中转库存
                $inventory = InventoryBoxFNSku::query()
                    ->where('account_id',$iBox->account_id)
                    ->where('warehouse_id',$iBox->warehouse_id)
                    ->where('fnsku',$fnSku)
                    ->lockForUpdate()
                    ->first();
                if($inventory){
                    $tempNum = $bTotal - $num;
                    $instant = $tempNum * $iBox->num_per_box; //中转在库库存 = 箱数差值 * 箱规格数量
                    $inventory->instant -= $instant;
                    if($inventory->instant < 0) {
                        $inventory->instant = 0;
                    }
                    $inventory->save();
                }

                //添加中转库存调整日志
                $adjustFNSku = BoxAdjust::query()->create(
                    [
                        'batch_no' => $batchNo,
                        'box_no' => $boxNo,
                        'fnsku' => $fnSku,
                        'warehouse_id' => $warehouseId,
                        'account_id' => $iBox->account_id,
                        'psku_id' => $iBox->psku_id,
                        'b_num' => $bTotal,
                        'a_num' => $aTotal,
                        'num_per_box' => $iBox->num_per_box,
                        'auser_id' => $userId,
                    ]
                );
                if(!$adjustFNSku){
                    DB::rollBack();
                    continue;
                }else{
                    DB::commit();
                }
            }
            if(empty($errors)){
                return ['flag' => true,'data' => $file->getClientOriginalName()];
            }else{
                return RExcel::importResult($errors);
            }
        }catch(\Exception $e){
            report($e);
            return ['flag' => false,'data' => '系统异常！'];
        }
    }

    public function template(Request $request){
        $temp = $request->get('temp');
        $suffix = $request->get('suffix','xlsx');
        return Storage::disk('admin')->download("template/{$temp}-template.{$suffix}");
    }
}
